<?php
/**
 * $Id: html.php 1167 2014-06-19 12:25:28Z shrey $
 * 
 * Extended HTML helper for things like generating buttons, tooltip, AJAX links etc.
 * 
 * Copyright 2005 - 2008, Giga Promoters
 * 						  608 Aggarwal Cyber Plaza
 *						  Netaji Subhash Place, Delhi - 110034
 *						  www.gigapromoters.com
 * 
 *
 * @version 			$Rev: 1167 $
 * @lastModifiedBy		$LastChangedBy: shrey $
 * @lastChanged			$Date: 2014-06-19 17:55:28 +0530 (Thu, 19 Jun 2014) $
 * @copyright 			Giga Promoters (www.gigapromoters.com)
 * 
 */
App::import('Helper','BaseHtml');
require_once(LIBS.'view'.DS.'helpers'.DS.'base_html.php'); // for error handler while tests

class HtmlHelper extends BaseHtmlHelper {
	
	protected $compressedFileStore;
	//will be used by compression.
	protected $themeCssFiles = array();
	var $inLayout = false;
	var $helpers = array('Javascript', 'Tooltip');
	function __construct()
	{
		parent::__construct();
		$this->mapExists = is_file(APP.'map.xml');
	}
	
	var $fullUrl = false;
	
	// @todo $full should be inside $options
	function url($url = null, $full = false, $options = array())
	{
		if($full==false)
			$full = $this->fullUrl;
			
		if(isset($options['shortUrl']) && $options['shortUrl'])
		{
			$fullUrl = cr('cmsConfig.Backend.siteUrl');
			$url = parent::url($url, $full);
			$shortUrl = Utility::makeBitlyUrl($fullUrl.$url);
			return $shortUrl;
		}
		else
		{
			return parent::url($url,$full);
		}

	}
	
	
	/**
	 * Generates a button without outputing a form
	 *
	 * @param unknown_type $title
	 * @param unknown_type $url
	 * @param unknown_type $options
	 * @return unknown
	 */
	function button($title, $url, $options=array())
	{
		$url = Configure::read('cmsConfig.Backend.siteUrl').$url;
		if(!isset($options['onclick']))
			$options['onclick'] = "document.location='".$url."';";
		$output = $this->tag('button', $title, $options);
		return $output;
	}
	
	function smartLink($title, $url = null, $htmlAttributes = array(), $confirmMessage = false, $escapeTitle = true)
	{
		$originalUrl = $url;
		$dispatcher = new Dispatcher();
		// check if its active link
		if(!is_array($url))
		{
			$url = $dispatcher->parseParams($url);
		}
		$currentAction = $this->params;
		$markActive = false;
		if(compareActions($url, $currentAction))
		{
			$markActive = true;
		}
		elseif(isset($htmlAttributes['matchConditions']))
		{
			$condition = $htmlAttributes['matchConditions'];
			$keysToMatch = array('plugin', 'controller', 'action');
			
			foreach($keysToMatch as $key)
			{
				//echo 'matched: '.$currentAction[$key].'<br>';
				if(isset($currentAction[$key]) && isset($condition[$key]))
				{
					$match = false;
					if(is_array($condition[$key]))
					{
						$match = in_array($currentAction[$key], $condition[$key]);
					}
					elseif(is_string($condition[$key]))
					{
						$match = ($currentAction[$key] == $condition[$key]);
					}
					elseif($condition[$key]=='*')
					{
						$match = true;
					}
					
					if(!$match)
					break;
				}
				
			}
			$markActive = $match;
			unset($htmlAttributes['matchConditions']);
		}
		if($markActive)
			$htmlAttributes = $this->addClass($htmlAttributes, 'active');
			
		/* @todo Left undone for now - added matchConditions in $htmlAttributes as a workaround until we solve reusable menu problem completely
		elseif($this->mapExists)
		{
			if($this->_ifChildrenActive($currentAction))
			{
				$htmlAttributes = $this->addClass($htmlAttributes, 'active');
			}
		}*/
		return $this->link($title, $originalUrl, $htmlAttributes, $confirmMessage, $escapeTitle);
	}
	


	/*
	function _ifChildrenActive($parentAction)
	{
		App::import('Xml'); 
		$parsed_xml =& new XML(APP.'map.xml');
    	$links = Set::reverse($parsed_xml);
    	
    	// locate current action
    	
    	//$links = $links[0];
    	//$parentAction = array('link'=>$parentAction);
    	//pr($links);
    	foreach($links['Main']['Link'] as $link)
    	{
    		if(isset($link['Children']))
    		{
    			foreach($link['Children'] as $childLink)
    			{
    				
    			}
    		}
    	}
    	exit;
	}*/

	/**
	 * Support for additional options:
	 * 'tooltip': To create a tooltip of the link
	 * 'tooltipStyle': Valid only when 'tooltip' paramater is set. Default style is 'cream'
	 *
	 * @param unknown_type $title
	 * @param unknown_type $url
	 * @param unknown_type $htmlAttributes
	 * @param unknown_type $confirmMessage
	 * @param unknown_type $escapeTitle
	 * @return unknown
	 */
	function link($title, $url = null, $htmlAttributes = array(), $confirmMessage = false, $escapeTitle = true)
	{
		$output = '';

		// @todo this code shouldn't be here
		if(isset($htmlAttributes['tooltip']))
		{
			if(!isset($htmlAttributes['tooltipOptions']))
			{
				$htmlAttributes['tooltipOptions'] = array();
			}
			$defaultTooltipOptions = array();
			$defaultTooltipOptions['show'] = array('when'=>array('event'=>"mouseover"));
			$defaultTooltipOptions['hide'] = array('when'=>array('event'=>"mouseout"));
			$defaultTooltipOptions['style'] = array('tip'=>"topMiddle");
			$defaultTooltipOptions['position']['corner'] = array('target'=>'bottomMiddle','tooltip'=>"topMiddle");
			$htmlAttributes['tooltipOptions'] = am($defaultTooltipOptions, $htmlAttributes['tooltipOptions']);

			if(!isset($htmlAttributes['id']))
			{
				$htmlAttributes['id'] = 'link_'.mt_rand();
			}
			$this->Tooltip->addQtipTooltip('#'.$htmlAttributes['id'], $htmlAttributes['tooltip'], $htmlAttributes['tooltipOptions']);
		}
		//at title attribute by using title text.
		if(!isset($htmlAttributes['title']))
		{
				$htmlAttributes['title'] = h(strip_tags($title));
		}
		$output .= parent::link($title, $url, $htmlAttributes, $confirmMessage, $escapeTitle);
		return $output;
	}

	/**
	 * Outputs AJAX link. Additional paramaters:
	 * updateInlineId => Shows response inside this DOM ID. Outputs JS alert if this option not set.
	 * successMessage => Can contain either %response% or a static message to show after request has been completed.
	 * 
	 * 
	 * @param unknown_type $title
	 * @param unknown_type $url
	 * @param unknown_type $htmlAttributes
	 * @param unknown_type $confirmMessage
	 * @param unknown_type $escapeTitle
	 * @return unknown
	 */
	function ajaxLink($title, $url = null, $htmlAttributes = array(), $confirmMessage = false, $escapeTitle = true)
	{
		$callBackFunction = "";
		if(isset($htmlAttributes['callback']))
		{
			$jsParams = '';
			if(isset($htmlAttributes['jsParams']))
			{
				$jsParams = implode(',', $htmlAttributes['jsParams']);
			}
			$callBackFunction .= "\n var el = $(this); var e = jQuery.Event('click');".$htmlAttributes['callback']."(".$jsParams.");";
			unset($htmlAttributes['callback']);
			unset($htmlAttributes['jsParams']);
		}

		
		// check ajax link type - simple alert link
		if(!isset($htmlAttributes['updateInlineId']))
		{
			if(!isset($htmlAttributes['successMessage']))
				$htmlAttributes['successMessage'] = "Success";
			$successAction = "alert(\"".$htmlAttributes['successMessage']."\");\n";

		}
		else {
			if($htmlAttributes['successMessage']=='%response%')
			{
				$responseData = 'response';
			}
			else {
				$responseData = '"'.$htmlAttributes['successMessage'].'"';
			}
			$successAction = "$('#".$htmlAttributes['updateInlineId']."').html(".$responseData.");";

		}
		
		
		$fullUrl = Configure::read('cmsConfig.Backend.siteUrl').$url;
		$htmlAttributes['onclick'] = '$.get("'.$fullUrl.'", function(response){'.
		$successAction .
		$callBackFunction
		.'}); return false;';
		unset($htmlAttributes['success']);
		unset($htmlAttributes['successMessage']);
		unset($htmlAttributes['updateInlineId']);
		$htmlAttributes['escape'] = true;
		$output = $this->link($title, $url, $htmlAttributes, $confirmMessage, $escapeTitle);
		return $output;
	}
	/**
	 * Function to include block wrapper
	 * 
	function getBlock($title, $content)
	{
		$output = "<h2>".$title."</h2>".$content;
		return $output;
	}
	*/

	function image($path, $options=array())
	{
		if($this->fullUrl==true)
		{
			if ($path[0] === '/') 
				$path = $this->webroot($path,true);
			else
				$path = Router::url($path,true);
		}
		if(isset($options['thumb']))
		{
			//echo "11";
			$path = $this->_generateThumbName($path, $options['thumb']);
			//echo $path; exit;
		}
		//echo $path; exit;
		
		if((isset($options['captify']) && $options['captify']==true) || Configure::read('useCaptify')==true)
		{
			$captionAttr = array('title'=>'','rel'=>'','alt'=>'');
			if(count(array_intersect_key($captionAttr,$options))>0)
			{
				$this->useCaptify = true;
				if(!isset($options['class']))
					$options['class'] ='';
					$options['class'] =' captify';
			}
		}
		unset($options['thumb']);
		//set title same as alt.
		if(isset($options['alt']))
		{
			$option['alt'] = strip_tags($options['alt']);
			$options['alt']  = h($options['alt']);
			if( !cr("Html.image.noTitle"))
			{
				$options['title'] = $options['alt'];
			}
 		}
		return parent::image($path,$options);
		//exit;
	}
	
	function defaultCss($exclude = array())
	{
		$css = array('/cms/css/libraries','/cms/css/template','/cms/css/grids'
					,'/cms/css/content','/cms/css/mod','/cms/css/mod_skins','/cms/css/main');
		$css = array_diff($css,$exclude);
		$out = $this->css($css);
		return $out;
	}
	
	function embedCode($url,$attributes=array())
	{
		$this->initHelper('Javascript');
		$id = 'embed_'.mt_rand();
		$out = '<div id="'.$id.'"></div>';
		$out .= '<script src="'.Configure::read('cmsConfig.Backend.siteUrl').'/cms/js/embed_code.js"></script>';
		$out .='<script type="text/javascript">var options = '.$this->Javascript->object($attributes).';var frame =  createIFame("'.$url.'",options);document.getElementById("'.$id.'").appendChild(frame)</script>';
		return $out;
	}
	
	function tablize($data, $options)
	{
		if(!isset($options['columns']))
		{
			trigger_error("Cannot use HtmlHelper::tablize() without 'columns' paramater");
			return false;
		}
			if(!isset($options['format']))
		{
			trigger_error("Cannot use HtmlHelper::tablize() without 'format' paramater");
		}		
		$output = "<table><tr>";
		$count = 1;
		//prd($this);
		foreach($data as $item)
		{
			$currentItem = "<td>";
			$currentItem .= $options['format']($item, $count, $this);
			$currentItem .= "</td>";
			$output .= $currentItem;
			
			if($count % $options['columns']==0)
			{
				$output .="</tr><tr>";
			}
			$count++;
		}		
		$output .= "</table>";
		return $output;
	}

	function beforeRender()
	{
		parent::beforeRender();
		if((isset($this->useCaptify) && $this->useCaptify==true )|| Configure::read('useCaptify')==true)
		{
			$view = ClassRegistry::getObject('view');
			$this->css('/cms/css/captify',null,array(),false);
			$this->Javascript->link('/cms/js/jquery.captify.js',false);
			$view->addScript('<script type="text/javascript">$(document).ready(function(){
				$([alt=""],[title=""],[rel=""]).removeClass("captify");
				$("img.captify").captify();
			})</script>');
		}
	}
	
	function _generateThumbName($imgUrl, $config)
	{
		//pr($imgUrl);
		//pr($config);
		//prd($config);
		if(is_string($config))
		{
			$config = Configure::read('Thumbs.'.$config);
		}
		$url = explode('/', $imgUrl);
		$file = end($url);
		array_pop($url);

		$tmp = explode('.', $file);
		
		$extension = array_pop($tmp);
		$imgName = implode('.', $tmp);

		$params = null;
		$params = "/thumbs";
		if(isset($config['crop']) && $config['crop'] == true)
		{
			$params .= '/crop';
		}	
		$params .= '/'.$config['width'];
		$params .= 'x'.$config['height'].'/';
	

		$uniqueFileName = implode("/", $url).$params.$imgName.'.'.$extension;
		return $uniqueFileName;
	}

	function css($path, $rel = null, $htmlAttributes = array(), $inline = true)
	{
		$assetCompression = cr('App.cssCompression');
		if($this->fullUrl==true)
		{
			if (strpos($path, '://') !== false) {
				$path = $path;
			} 
			else
			{
				if ($path[0] !== '/') 
				{
					$path = CSS_URL . $path;
				}
				if (strpos($path, '?') === false) 
				{
					if (strpos($path, '.css') === false) 
					{
						$path .= '.css';
					}
				}
				$path = $this->webroot($path);
				$path = preg_replace('/^'.preg_quote($this->base,'/').'/','/',$path);
			}
			$path = $this->url($path,true);
		}
		$actualInline = $inline;
		//need to add to compression even when it is inline false;
		if($assetCompression)
		{
			$inline = true;
		}
		$out =  parent::css($path,$rel, $htmlAttributes, $inline);
		//checks only single file.
		if($assetCompression && preg_match('/<link.+ \/>/',$out))
		{
			$src = null;
			$matches = array();
			preg_match_all('/href="(.+)"/',$out,$matches);
			if(isset($matches[1][0]))
			{
				$src = $matches[1][0];
			}
			//if ignore themed files compression
			if($src && cr("App.ignoreThemedCompression") !== false)
			{
				$regex = str_replace('/','\/',$this->webroot).'themed\/.+';
				if(preg_match("/$regex/",$src))
				{
					$src = null;
					$this->themeCssFiles[] = $out;
					$out = null;
				}
			}
			if($src)
			{
				$this->compressCss($src);
				$out = null;
			}
		}
		return $out;
	}
	
	function menu(LinkCollection $links, $parent, $options = array())
	{
		if(!$parent)
		{
			return null; // hack for now
		}
		//echo $parent;
		//$linksArr = $links->getLinks($parent);
		$output = '';
		$defaultOptions = array(
			'menuWrapper' => 'ul',
			'linkWrapper' => 'li',
			'activeClass' => 'active',
			'wrapperOptions' => array()
		);
		$options = am($defaultOptions, $options);
		extract($options);
		$linkObjArr = $links->getLinks($parent);
		//prd($linkObjArr);
		if(!$linkObjArr)
		{
			return null;
		}
		//prd($linkObjArr);
		foreach($linkObjArr as $linkObj)
		{
			$link = $linkObj->toArray();
			
			$linkWrapperOptions = array();
			if(isset($link['options']['parent']))
			{
				$linkWrapperOptions = $link['options']['parent'];
				unset($link['options']['parent']);
			}
			if($linkObj->isActive())	
			{
				$link['options'] = $this->addClass($link['options'], $activeClass);
				$linkWrapperOptions = $this->addClass($linkWrapperOptions, $activeClass);
			}
			$link = $this->link($link['title'], $link['url'], $link['options']);
			if($linkWrapper)
				$output .= $this->tag($linkWrapper, $link, $linkWrapperOptions);
			else
				$output .= $link; 
		}
		if(!$menuWrapper)
			return $output;
		else
		{
			$output = $this->tag($menuWrapper, $output, $wrapperOptions);
		}
		return $output;
	}
	
	/**
	 * Handy function to save time while creating view pages
	 */
	function showRecord($record, $modelAlias)
	{
		$output = "<table>";
		$model = ClassRegistry :: getObject($modelAlias);
		foreach($record[$modelAlias] as $field => $value)
		{
			$output .= "<tr>";
			if(is_object($model))
			{
				
				$fieldLabel = $model->getFieldProperties($field, 'label');
				$valueToDisplay = $model->showValue($field, $record[$modelAlias]);
			}
			else
			{
				$fieldLabel = Inflector::humanize($field);
				$valueToDisplay = $value;
			}
			$output .= "<td>".$fieldLabel."</td><td>".$valueToDisplay."</td></tr>";
		}
		$output .= "</table>";
		return $output;
	}
	
	/**
	 * 
	 */
	function beforeLayout()
	{
		$this->inLayout = true;
		parent::beforeLayout();
	}
	function afterLayout()
	{
		$this->inLayout = false;
	}
	
	/**
	 * Add a file to compression array
	 * @param unknown_type $path
	 * @param unknown_type $type
	 */
	private function compressCss($path)
	{
		if(!is_object($this->compressedFileStore))
		{
			App::import('Vendor','Cms.compression/CompressionFileStore');
			$this->compressedFileStore = new CompressionFileStore(CompressionFileStore::TYPE_CSS,$this->webroot);
		}
		$fn = 'addPreFile';
		if($this->inLayout == true)
		{
			$fn = 'addPostFile';
		}
		$this->compressedFileStore->$fn($path);
	}
	
	function getCompressedCss($name = 'combined')
	{
		$compressedCss = null;
		if(cr('App.cssCompression') == true && is_object($this->compressedFileStore))
		{
			$url = $this->compressedFileStore->getCompressedFileUrl($name);
			$compressedCss =  parent::css($url);
			$compressedCss .= implode("\n",$this->themeCssFiles); 
		}
		return $compressedCss;
	}

}
?>